import { ref, reactive } from "vue";
import L, {
  type Map,
  type Marker,
  type MarkerClusterGroup,
  type Circle,
  type Polygon
} from "leaflet";
import "leaflet.markercluster";

/** 标记集群配置项 */
interface MarkerClusterOption {
  /**标记点点击事件监听 */
  onClick?: Function;
}

/** 圆形区域配置项 */
export interface CircleConfig {
  /** 颜色 */
  color?: string;
  /** 填充颜色 */
  fillColor?: string;
  /** 填充透明度 */
  fillOpacity?: number;
  /** 半径(米) */
  radius: number;
  /** 弹出窗口内容 */
  popupContent?: string;
}

/** 多边形配置项 */
export interface PolygonConfig {
  /** 顶点坐标数组 */
  latlngs: [number, number][];
  /** 颜色 */
  color?: string;
  /** 填充颜色 */
  fillColor?: string;
  /** 填充透明度 */
  fillOpacity?: number;
  /** 弹出窗口内容 */
  popupContent?: string;
}

/** 标记配置项 */
export interface MarkerConfig {
  /** 是否启用集群 */
  cluster?: boolean;
  /** 集群配置 */
  clusterOptions?: MarkerClusterOption;
  /** 默认标记图标配置 */
  iconOptions?: L.IconOptions;
  /** 是否启用点击事件 */
  enableClick?: boolean;
  /** 默认圆形配置 */
  defaultCircleConfig?: CircleConfig;
  /** 默认多边形配置 */
  defaultPolygonConfig?: PolygonConfig;
}

/** 标记数据类型 */
export interface MarkerData {
  /** 唯一标识 */
  id?: string | number;
  /** 纬度 */
  lat: number;
  /** 经度 */
  lng: number;
  /** 弹出窗口内容 */
  popupContent?: string;
  /** 自定义选项 */
  options?: any;
}

/** 创建标记集群 */
const cerateMarkerCluster = (
  map: Map,
  opt?: MarkerClusterOption
): MarkerClusterGroup => {
  const markercluster = L.markerClusterGroup({
    disableClusteringAtZoom: 18
  });
  if (opt?.onClick) {
    markercluster.on("click", opt.onClick);
  }
  map.addLayer(markercluster);
  return markercluster;
};

export function useMarkers(map: Map, config: MarkerConfig = {}) {
  // 状态管理
  const markersVisible = ref(true);
  const markers = ref<{ [key: string]: Marker }>({});
  const circles = ref<{ [key: string]: Circle }>({});
  const polygons = ref<{ [key: string]: Polygon }>({});
  const markerCluster = ref<MarkerClusterGroup | null>(null);
  const activeMarker = ref<Marker | null>(null);

  // 默认配置
  const defaultConfig = reactive<MarkerConfig>({
    cluster: config.cluster ?? false,
    clusterOptions: config.clusterOptions ?? {},
    iconOptions: config.iconOptions ?? {
      iconUrl: "https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png",
      iconSize: [25, 41],
      iconAnchor: [12, 41],
      popupAnchor: [1, -34]
    },
    enableClick: config.enableClick ?? true,
    defaultCircleConfig: config.defaultCircleConfig ?? {
      color: "red",
      fillColor: "#f03",
      fillOpacity: 0.5,
      radius: 500
    },
    defaultPolygonConfig: config.defaultPolygonConfig ?? {
      color: "blue",
      fillColor: "#00f",
      fillOpacity: 0.3
    }
  });

  // 初始化标记集群
  const initMarkerCluster = () => {
    if (!map.value || !defaultConfig.cluster) return;
    markerCluster.value = cerateMarkerCluster(
      map.value,
      defaultConfig.clusterOptions
    );
  };

  // 创建单个标记
  const createMarker = (data: MarkerData): Marker => {
    const markerId = data.id || `${data.lat}-${data.lng}`;
    const marker = L.marker([data.lat, data.lng], {
      icon: L.icon(defaultConfig.iconOptions),
      ...data.options
    });

    // 绑定弹出窗口
    if (data.popupContent) {
      marker.bindPopup(data.popupContent);
    }

    // 点击事件处理
    if (defaultConfig.enableClick) {
      marker.on("click", () => {
        activeMarker.value = marker;
      });
    }

    markers.value[markerId] = marker;
    return marker;
  };

  // 添加单个标记到地图
  const addMarker = (data: MarkerData): Marker => {
    if (!map.value) return;
    const marker = createMarker(data);

    if (defaultConfig.cluster && markerCluster.value) {
      markerCluster.value.addLayer(marker);
    } else {
      marker.addTo(map.value);
    }
    return marker;
  };

  // 添加圆形区域
  const addCircle = (
    latlng: [number, number],
    config: CircleConfig,
    id?: string | number
  ): Circle => {
    if (!map.value) return;
    const circleId = id || `circle-${latlng[0]}-${latlng[1]}`;
    const circle = L.circle(latlng, {
      ...defaultConfig.defaultCircleConfig,
      ...config
    });

    if (config.popupContent) {
      circle.bindPopup(config.popupContent);
    }

    circle.addTo(map.value);
    circles.value[circleId] = circle;
    return circle;
  };

  // 添加多边形
  const addPolygon = (
    latlngs: [number, number][],
    config: PolygonConfig,
    id?: string | number
  ): Polygon => {
    if (!map.value) return;
    const polygonId = id || `polygon-${Date.now()}`;
    const polygon = L.polygon(latlngs, {
      ...defaultConfig.defaultPolygonConfig,
      ...config
    });

    if (config.popupContent) {
      polygon.bindPopup(config.popupContent);
    }

    polygon.addTo(map.value);
    polygons.value[polygonId] = polygon;
    return polygon;
  };

  // 批量添加标记
  const addMarkers = (dataList: MarkerData[]): void => {
    if (!map.value) return;
    dataList.forEach(data => addMarker(data));
  };

  // 移除单个标记
  const removeMarker = (id: string | number): void => {
    const marker = markers.value[id];
    if (marker) {
      if (defaultConfig.cluster && markerCluster.value) {
        markerCluster.value.removeLayer(marker);
      } else if (map.value) {
        map.value.removeLayer(marker);
      }
      delete markers.value[id];
    }
  };

  // 移除圆形
  const removeCircle = (id: string | number): void => {
    const circle = circles.value[id];
    if (circle && map.value) {
      map.value.removeLayer(circle);
      delete circles.value[id];
    }
  };

  // 移除多边形
  const removePolygon = (id: string | number): void => {
    const polygon = polygons.value[id];
    if (polygon && map.value) {
      map.value.removeLayer(polygon);
      delete polygons.value[id];
    }
  };

  // 清除所有标记
  const clearMarkers = (): void => {
    if (defaultConfig.cluster && markerCluster.value) {
      markerCluster.value.clearLayers();
    } else if (map.value) {
      Object.values(markers.value).forEach(marker => {
        map.value!.removeLayer(marker);
      });
    }
    markers.value = {};
  };

  // 清除所有圆形
  const clearCircles = (): void => {
    if (map.value) {
      Object.values(circles.value).forEach(circle => {
        map.value!.removeLayer(circle);
      });
    }
    circles.value = {};
  };

  // 清除所有多边形
  const clearPolygons = (): void => {
    if (map.value) {
      Object.values(polygons.value).forEach(polygon => {
        map.value!.removeLayer(polygon);
      });
    }
    polygons.value = {};
  };

  // 清除所有图形元素
  const clearAll = (): void => {
    clearMarkers();
    clearCircles();
    clearPolygons();
  };

  // 切换标记显示状态
  const toggleMarkers = (): void => {
    markersVisible.value = !markersVisible.value;
    if (defaultConfig.cluster && markerCluster.value) {
      if (markersVisible.value) {
        map.value?.addLayer(markerCluster.value);
      } else {
        map.value?.removeLayer(markerCluster.value);
      }
    } else {
      Object.values(markers.value).forEach(marker => {
        if (markersVisible.value) {
          marker.addTo(map.value!);
        } else {
          map.value?.removeLayer(marker);
        }
      });
    }
  };

  // 地图点击事件处理
  const handleMapClick = (callback?: (latlng: L.LatLng) => void) => {
    if (!map.value) return;
    map.value.on("click", (e: L.LeafletMouseEvent) => {
      L.popup()
        .setLatLng(e.latlng)
        .setContent(`你点击了地图位置: ${e.latlng.toString()}`)
        .openOn(map.value!);
      if (callback) {
        callback(e.latlng);
      }
    });
  };

  // 初始化地图元素
  const initMapElements = (
    center: [number, number],
    circleConfig?: CircleConfig,
    polygonPoints?: [number, number][]
  ) => {
    // 添加默认标记
    addMarker({
      lat: center[0],
      lng: center[1],
      popupContent: "<b>北京天安门</b><br>中国首都的中心位置."
    });

    // 添加默认圆形
    if (circleConfig) {
      addCircle(center, {
        ...circleConfig,
        popupContent: "天安门周边区域"
      });
    }

    // 添加默认多边形
    if (polygonPoints) {
      addPolygon(polygonPoints, {
        popupContent: "这是一个多边形区域"
      });
    }

    // 绑定点击事件
    handleMapClick();
  };

  // 初始化
  const init = () => {
    if (defaultConfig.cluster) {
      initMarkerCluster();
    }
  };

  // 销毁清理
  const destroy = () => {
    clearAll();
    if (markerCluster.value && map.value) {
      map.value.removeLayer(markerCluster.value);
      markerCluster.value = null;
    }
  };

  return {
    config: defaultConfig,
    markersVisible,
    markers,
    circles,
    polygons,
    activeMarker,
    markerCluster,
    init,
    addMarker,
    addMarkers,
    addCircle,
    addPolygon,
    removeMarker,
    removeCircle,
    removePolygon,
    clearMarkers,
    clearCircles,
    clearPolygons,
    clearAll,
    toggleMarkers,
    handleMapClick,
    initMapElements,
    destroy
  };
}
